import javax.swing.JTextArea;
import java.io.*;
import java.util.StringTokenizer;
import java.text.DecimalFormat;

public class Weapon extends Item implements Entity, Serializable {
	
	private enum Type { SWORD, DAGGER, AXE, POLEARM, MACE, GREATSWORD, GREATAXE, MAUL, FISTS }
	private enum Material { BRONZE, IRON, STEEL, SILVER, BONE }
	private enum Quality { CRUDE, COMMON, SUPERIOR, EPIC, EXQUISITE, LEGENDARY }
	private Type weapon_type;
	private Material material;
	private Quality quality;
	private String dmgType;

	
	public Weapon(String g, String a, String b, String c, String ...strings ) {
	
		
		super(g, b, c, "", 1);
		setType(c);
		setMaterial(b);
		setQuality(a);
		calcValue();
		
		super.DisplayName = ("a " + quality.toString().toLowerCase() + " " + material.toString().toLowerCase() + " " + weapon_type.toString().toLowerCase());
		if (weapon_type == Type.FISTS) {
			super.Name = "fists";
		} else {
			super.Name = (quality.toString().toLowerCase() + " " + material.toString().toLowerCase() + " " + weapon_type.toString().toLowerCase());
		}
		super.Weight = calcWeight();
		setDmgType();
		if (weapon_type != Type.FISTS) {
		setDescription();
		} else {
			
		}
		
		if (strings.length > 0) {
			super.Name = strings[0];
		}
		
	}
	
	public void Display(JTextArea y) {
		y.append(Orientation + " is " + DisplayName + ". ");
	}
	
	public void setQuality(String a) {
		for (Quality b : Quality.values()) {
			if (b.toString().equalsIgnoreCase(a)) {
				quality = b;
			}
		}
	}
	
	public double getWeight() {
		return this.Weight;
	}
	
	public void calcValue() {
		double result = 0.0;
		double weapon_base_value = 0.0;
		switch (weapon_type) {
		case DAGGER:
			weapon_base_value = 20.0;
			break;
		case AXE:
			weapon_base_value = 40.0;
			break;
		case SWORD:
			weapon_base_value = 40.0;
			break;
		case FISTS:
			weapon_base_value = 0.0;
			break;
		case MAUL:
			weapon_base_value = 100.0;
			break;
		}
		
		double material_value_modifier = 0.0;
		switch (material) {
		case BONE:
			material_value_modifier = 0.5;
			break;
		case BRONZE:
			material_value_modifier = 1.0;
			break;
		case IRON:
			material_value_modifier = 1.5;
			break;
		case STEEL:
			material_value_modifier = 2.0;
			break;
		case SILVER:
			material_value_modifier = 4.0;
			break;
		default:
			material_value_modifier = 1.0;
			break;
		}
		
		double quality_value_modifier = 0.0;
		
		switch (quality) {
		case CRUDE:
			quality_value_modifier = 0.5;
			break;
		case COMMON:
			quality_value_modifier = 1.0;
			break;
		case SUPERIOR:
			quality_value_modifier = 1.5;
			break;
		case EXQUISITE:
			quality_value_modifier = 3.0;
			break;
		case EPIC:
			quality_value_modifier = 5.0;
			break;
		case LEGENDARY:
			quality_value_modifier = 6.0;
			break;
		default:
			quality_value_modifier = 1.0;
			break;
		}
		
		result = ((weapon_base_value * material_value_modifier) * quality_value_modifier);
		super.value = (int) Math.rint(result);
		
	}
	
	public void setMaterial(String a) {
		for (Material b : Material.values()) {
			if (b.toString().equalsIgnoreCase(a)) {
				material = b;
			}
		}
	}
	
	public int calcDamage(Player a) {
		double damage = 0.0;
		
		switch (weapon_type) {
		case DAGGER:
			damage = (((a.get_Main_Hand().getWeight() * 0.25) * (getDmg_Modifier() * 3)) * (a.getAgility()));
			break;
		case AXE:
			damage = (((a.get_Main_Hand().getWeight() * 1) * getDmg_Modifier()) * a.getStrength());
			break;
		case SWORD:
			damage = (((a.get_Main_Hand().getWeight() * 0.75) * (getDmg_Modifier() * 2)) * ((a.getStrength() * 0.5) + (a.getAgility() * 0.5)));
			break;
		case FISTS:
			damage = (getDmg_Modifier() * (a.getStrength() + a.getAgility()));
			break;
		case MAUL:
			damage = ((a.get_Main_Hand().getWeight() * a.getStrength()) * (getDmg_Modifier() / 3));
			break;
		}
		
		
		
		int result = (int) Math.rint(damage);
		return result;
	}
	
	public int calcDamage(Character a) {
		double damage = 0.0;
		
		switch (weapon_type) {
		case DAGGER:
			damage = (((a.get_Main_Hand().getWeight() * 0.25) * (getDmg_Modifier() * 3)) * (a.getAgility() * 2));
			break;
		case AXE:
			damage = (((a.get_Main_Hand().getWeight() * 1) * getDmg_Modifier()) * a.getStrength());
			break;
		case SWORD:
			damage = (((a.get_Main_Hand().getWeight() * 0.75) * (getDmg_Modifier() * 2)) * ((a.getStrength() * 0.5) + (a.getAgility() * 0.5)));
			break;
		case FISTS:
			damage = (getDmg_Modifier() * (a.getStrength() + a.getAgility()));
			break;
		case MAUL:
			damage = ((a.get_Main_Hand().getWeight() * a.getStrength()) * (getDmg_Modifier() / 2));
			break;
		}		
		int result = (int) Math.rint(damage);
		return result;
	}
	
	
	public double getDmg_Modifier() {
		double result;
		
		switch (quality) {
		case CRUDE:
			result = 1.0;
			break;
		case COMMON:
			result = 1.2;
			break;
		case SUPERIOR:
			result = 1.4;
			break;
		case EXQUISITE:
			result = 1.6;
			break;
		case EPIC:
			result = 1.8;
			break;
		case LEGENDARY:
			result = 2.0;
			break;
		default:
			result = 1.0;
			break;
		}
		
		return result;
	}
	
	public double calcWeight() {
		double baseweight = 0.0;
		
		switch (weapon_type) {
		case DAGGER:
			baseweight = 1.5;
			break;
		case SWORD:
			baseweight = 4.0;
			break;
		case AXE:
			baseweight = 6.0;
			break;
		case MACE:
			baseweight = 8.0;
			break;
		case POLEARM:
			baseweight = 12.0;
			break;
		case FISTS:
			baseweight = 1.0;
			break;
		case MAUL:
			baseweight = 20.0;
			break;
		default:
			baseweight = 2.0;
			break;
		}
		
		double materialmodifier = 0.0;
		
		switch (material) {
		case BONE:
			materialmodifier = 0.75;
			break;
		case BRONZE:
			materialmodifier = 1.0;
			break;
		case IRON:
			materialmodifier = 1.20;
			break;
		case STEEL:
			materialmodifier = 1.30;
			break;
		case SILVER:
			materialmodifier = 1.40;
			break;
		default:
			materialmodifier = 40.0;
			break;
		}
		
		double result = baseweight * materialmodifier;
		return result;
	}
	
	public void setType(String a) {
		for (Type b : Type.values()) {
			if (b.toString().equalsIgnoreCase(a)) {
				weapon_type = b;
			}
		}
	}
	
	public void setDmgType() {
		switch (weapon_type) {
		case DAGGER:
			dmgType = "stab";
			break;
		case SWORD:
			dmgType = "slash";
			break;
		case AXE:
			dmgType = "hack";
			break;
		case MACE:
			dmgType = "smash";
			break;
		case FISTS:
			dmgType = "punch";
			break;
		default:
			dmgType = "attack";
			break;
		}
	}
	
	public String getDmgType() {
		return dmgType;
	}
	
	public String getWeaponType() {
		return weapon_type.toString();
	}
	
	public void setDescription() {
		StringTokenizer title = new StringTokenizer(Name);
		String a1 = title.nextToken();
		a1 = title.nextToken();
		String a2 = title.nextToken();
		String Title = (a1 + " " + a2);
		switch (quality) {
		case CRUDE:
			Description = ("It's a crudely fashioned " + Title + ". The hilt isn't particularly comfortable and it feels off-balance, reducing its effectiveness in combat");
			if (material == Material.SILVER) {
				Description = Description + ". Despite the poor craftsmanship, its silver content renders it nonetheless fairly valuable";
			}
			break;
		case COMMON:
			Description = ("It's a competently made " + Title + ", about average in terms of quality. Solid and dependable without particularly standing out");
			if (material == Material.SILVER) {
				Description = Description + ", though the silver content does elevate it beyond the mundane";
			}
			break;
		case SUPERIOR:
			Description = ("It's a well-fashioned " + Title + ", it feels comfortable in your hand and the skill of the craftsman ensures it is well-balanced for striking. This is the kind of weapon an officer might wield, or someone who can afford equipment that's a cut above the usual");
			break;
		case EXQUISITE:
			Description = ("This is a beautifully-made " + Title + ". The hilt is padded with leather and it feels perfectly balanced to provide the wielder an advantage in battle. Intricate designs are etched into the head, and a ruby adorns the pommel. This is a fine weapon indeed");
			break;
		case EPIC:
			Description = ("This " + Title + " seems to shine with its own inner power, and as you gaze upon the scenes of battle etched into it, you could almost swear they come to life before your very eyes");
			break;
		case LEGENDARY:
			Description = ("It seems to radiate power, drawing your gaze inextricably to its glow. It almost feels like it is wielding you rather than you wielding it");
			break;
		}
	}
	
}
